#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <dirent.h>
#include <sys/time.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <pwd.h>

#include "data_type.h"
#include "cube.h"
#include "cube_define.h"
#include "cube_record.h"

#include "json.h"

#include "shell_list.h"
#include "cmdlist_run.h"

#define MAX_LINE_LEN 1024

static unsigned char Buf[DIGEST_SIZE*32];

int cmdlist_run_init(void * sub_proc,void * para)
{
    int ret;

    return 0;
}

int cmdlist_run_start(void * sub_proc,void * para)
{
    		
    int ret = 0, len = 0, i = 0, j = 0;
    int rc = 0;
    struct start_para * start_para = para;

    int type,subtype;	

    void * recv_msg;


    while(1)
    {
        usleep(time_val.tv_usec);

		ret=ex_module_recvmsg(sub_proc,&recv_msg);
		if(ret<0)
			continue;
		if(recv_msg==NULL)
			continue;
		type=message_get_type(recv_msg);
		subtype=message_get_subtype(recv_msg);
		if(!memdb_find_recordtype(type,subtype))
		{
			printf("message format (%d %d) is not registered!\n",
			message_get_type(recv_msg),message_get_subtype(recv_msg));
			continue;
		}
		if((type==TYPE(GENERAL_RETURN))&&(subtype==SUBTYPE(GENERAL_RETURN,STRING)))
		{
			ret=proc_cmdlist_run(sub_proc,recv_msg);
		}
	}
    return 0;
}

int proc_cmdunit_run(RECORD(SHELL_LIST,CMD_UNIT) * cmd_unit)
{
    pid_t fpid; //fpid表示fork函数返回的值  
    int count=0;  
    fpid=fork();   
    if (fpid < 0) 
    {
          print_cubeerr("error in fork!");  
          return -EINVAL;
    }
    if (fpid == 0) {  
	int status;
        print_cubeaudit("cmdlist_run: prepare run %s and sleep %d !",cmd_unit->cmd_line,cmd_unit->delay);
        status = system(cmd_unit->cmd_line);
	if (-1 == status)
        {
        	print_cubeerr("cmdlist_run: system run %s error!",cmd_unit->cmd_line);
          	exit(-EINVAL);
        }
        else
        {
            if (WIFEXITED(status))
            {
               if (0 == WEXITSTATUS(status))
               {
       //   	  print_cubeaudit("cmdlist_run: system run %s succeed!",cmd_unit->cmd_line);
                  exit(0);
               }
               print_cubeerr("cmdlist_run: run shell script %s fail, script exit code: %d\n", 
			cmd_unit->cmd_line,WEXITSTATUS(status));
              	exit(-EINVAL);
            }
             print_cubeerr("cmdlist_run: shell script %s exit fail, script exit code: %d\n", 
			cmd_unit->cmd_line,WEXITSTATUS(status));
             exit(-EINVAL);
        }
        exit(0);
    }  
    
     if(cmd_unit->delay>0)
     {
         print_cubeaudit("cmdlist_run: prepare sleep %d us!",cmd_unit->delay);
         usleep(cmd_unit->delay);
    }
     return 0;
}

int proc_cmdset_run(void * sub_proc, RECORD(SHELL_LIST,CMD_SET) * cmd_set, void *recv_msg)
{
	int ret;
	int i;
	void * send_msg;
	DB_RECORD * db_record;
	int unit_seq=0;
	RECORD(SHELL_LIST,CMD_UNIT) * comp_unit;
    	RECORD(GENERAL_RETURN,STRING) * shell_notice;
	BYTE uuid[DIGEST_SIZE];

	shell_notice = Talloc0(sizeof(*shell_notice));
	if(shell_notice == NULL)
		return -ENOMEM;
        shell_notice->return_value  = dup_str(cmd_set->cmdset_desc,128);
        shell_notice->name = dup_str(cmd_set->item_name,32);
        send_msg=message_create(TYPE_PAIR(GENERAL_RETURN,STRING),recv_msg);
        if(send_msg==NULL)
            	return -EINVAL;
        message_add_record(send_msg,shell_notice);
        ex_module_sendmsg(sub_proc,send_msg);

	comp_unit = Talloc0(sizeof(*comp_unit));
	if(comp_unit == NULL)
		return -ENOMEM;
	comp_unit->item_name=dup_str(cmd_set->item_name,64);
	comp_unit->set_name=dup_str(cmd_set->set_name,64);

	for(unit_seq=1;unit_seq<= cmd_set->cmd_num;unit_seq++)
	{
		comp_unit->seq_no=unit_seq;
		memdb_comp_record_uuid(comp_unit,TYPE_PAIR(SHELL_LIST,CMD_UNIT),uuid);
		db_record=memdb_find(uuid,TYPE_PAIR(SHELL_LIST,CMD_UNIT));
		if(db_record == NULL)
		{
			print_cubeerr("cmdlist_run: set %s can't find cmd!",cmd_set->set_name);
			return -EINVAL;
		}

		ret = proc_cmdunit_run(db_record->record);
		if(ret<0)
		{
			print_cubeerr("cmdlist_run: run cmd fail!");
			return ret;
		}		
	}

	return unit_seq;
}

int proc_cmdlist_run(void * sub_proc,void * recv_msg)
{
    int ret;
    int i=0;

    RECORD(SHELL_LIST,CMD_SET) * comp_set;
    RECORD(GENERAL_RETURN,STRING) * cmd_item;
    DB_RECORD * db_record;
    int seq_no=0;
    BYTE uuid[DIGEST_SIZE];


    ret = message_get_record(recv_msg,&cmd_item,0);
    if(ret<0)
        return ret;

	comp_set = Talloc0(sizeof(*comp_set));
	if(comp_set == NULL)
		return -ENOMEM;
	comp_set->item_name=dup_str(cmd_item->return_value,64);

	comp_set->seq_no=1;
	
    do{
		memdb_comp_record_uuid(comp_set,TYPE_PAIR(SHELL_LIST,CMD_SET),uuid);
		db_record=memdb_find(uuid,TYPE_PAIR(SHELL_LIST,CMD_SET));
		if(db_record == NULL)
			break;
		proc_cmdset_run(sub_proc,db_record->record,recv_msg);
		comp_set->seq_no++;

	}while(1);

	return comp_set->seq_no;
    return 0; 
}
